package com.example.hjlquickstartdemo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.example.hjlquickstartdemo.constant.GlobalConstant;
import com.example.hjlquickstartdemo.dao.entity.User;
import com.example.hjlquickstartdemo.dao.mapper.UserMapper;
import com.example.hjlquickstartdemo.exception.AllErrorCode;
import com.example.hjlquickstartdemo.exception.BusinessException;
import com.example.hjlquickstartdemo.pojo.dto.UserDto;
import com.example.hjlquickstartdemo.pojo.query.UserQuery;
import com.example.hjlquickstartdemo.pojo.vo.CommonPage;
import com.example.hjlquickstartdemo.service.UserService;
import com.example.hjlquickstartdemo.utils.IdGenerator;
import com.github.pagehelper.Page;
import com.github.pagehelper.page.PageMethod;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;


import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 服务实现类
 *
 * @author HeJiaLe
 * @date 2023/07/17 11:21
 **/

@Service
@Slf4j
public class UserServiceImpl implements UserService {
    /**
     * 用户姓名列
     */
    private static final String PROPERTY_NAME = "name";
    /**
     * 用户身份证id列
     */
    private static final String PROPERTY_CITIZEN_ID = "citizen_id";
    /**
     * 数据更新时间
     */
    private static final String PROPERTY_UPDATED_TIME = "updated_time";

    @Autowired
    private UserMapper UserMapper;
    @Autowired
    private IdGenerator idGenerator;

    @Override
    public Boolean add(UserDto userDto) {
        // 业务规则校验身份证号不可重复
        if (null != this.findUserByCitizenId(userDto.getCitizenId(), null)) {
            throw new BusinessException(AllErrorCode.DATA_SEARCH_FOUND_MANY, "系统存在相同身份证号用户");
        }
        User user = new User();
        //浅拷贝，复制的过程是通过对两个对象的属性进行逐一的赋值操作实现的。如果两个对象的属性名相同，类型也匹配，那么属性值会被复制到目标对象中。
        BeanUtils.copyProperties(userDto, user);
        user.setId(idGenerator.snowflakeId());
        user.setCreatedBy(idGenerator.snowflakeId());
        user.setCreatedTime(new Date());
        user.setVersion(idGenerator.snowflakeId());
        user.setStatus(GlobalConstant.ROW_DATA_STATUS_ACTIVE);
        //log.info("test dev-tools");
        return UserMapper.insert(user) > 0;
    }

    @Override
    public User findUserByCitizenId(String citizenId, Long exclusiveId) {
        if (StringUtils.isEmpty(citizenId)) {
            throw new BusinessException(AllErrorCode.PARAM_VALID_FIELD_REQUIRE, "id不可以为空");
        }
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();

        if (exclusiveId == null) {
            queryWrapper.eq(PROPERTY_CITIZEN_ID, citizenId);
        } else {
            // 排除当前记录
            queryWrapper.eq(PROPERTY_CITIZEN_ID, citizenId)
                    .ne(GlobalConstant.TableCommonField.ID_COLULMN_NAME, exclusiveId);
        }
        return UserMapper.selectOne(queryWrapper);
    }

    @Override
    public Boolean remove(Long id) {
        return UserMapper.deleteById(id) > 0;
    }

    @Override
    public Boolean update(UserDto userDto) {
        if (null == userDto.getId()) {
            throw new BusinessException(AllErrorCode.PARAM_VALID_FIELD_REQUIRE, "id为主键列不可为空");
        }
        // 判断系统不存在相同身份证号的
        if (findUserByCitizenId(userDto.getCitizenId(), userDto.getId()) != null) {
            throw new BusinessException(AllErrorCode.DATA_SEARCH_FOUND_MANY,
                    "身份证号系统已经使用，请换一个");
        }
        User user = new User();
        BeanUtils.copyProperties(userDto, user);
        user.setUpdatedTime(new Date());
        user.setUpdatedBy(GlobalConstant.DEFAULT_MODIFIOR_ID);
        // 更新版本id
        user.setVersion(idGenerator.snowflakeId());
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper
                .eq(GlobalConstant.TableCommonField.ID_COLULMN_NAME, userDto.getId())
                .eq(GlobalConstant.TableCommonField.VERSION_COLUMN_NAME, userDto.getVersion());
        return UserMapper.update(user, updateWrapper) > 0;
    }

    @Override
    public CommonPage<UserDto> search(UserQuery UserQuery) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        // 前端的查询条件是 and 关系所以一下用andlike
        if (!StringUtils.isEmpty(UserQuery.getName())) {
            queryWrapper.like(PROPERTY_NAME, "%" + UserQuery.getName().trim() + "%");
        }
        if (!StringUtils.isEmpty(UserQuery.getCitizenId())) {
            queryWrapper.like(PROPERTY_CITIZEN_ID, "%" + UserQuery.getCitizenId().trim() + "%");
        }
        queryWrapper.orderByDesc(PROPERTY_UPDATED_TIME);
        /**
         * 构建包含分页信息的列表
         */
        PageMethod.startPage(UserQuery.getPageIndex(), UserQuery.getPageSize());
        Page<User> userPage = (Page<User>) UserMapper.selectList(queryWrapper);
        List<UserDto> userDtoList = new ArrayList<>();
        for (User element : userPage) {
            UserDto copyElement = new UserDto();
            // 将源列表中的元素属性值复制到新对象中
            BeanUtils.copyProperties(element, copyElement);
            userDtoList.add(copyElement);
        }
        log.debug(String.format("pageNum=%d,pages=%d,total=%d,pageSize=%d ", userPage.getPageNum(), userPage.getPages(),
                userPage.getTotal(), userPage.getPageSize()));
        return new CommonPage(userPage.getTotal(), userPage.getPageNum(), userPage.getPageSize(), userPage.getPages(), userDtoList);
    }

    @Override
    public UserDto findById(Long id) {
        User User = UserMapper.selectById(id);
        UserDto userDto = new UserDto();
        BeanUtils.copyProperties(User, userDto);
        return userDto;
    }
}
